﻿#ifndef CANMANAGE_H
#define CANMANAGE_H

#include "xict_common/utils/types.h"
#include "xict_proto/common/lane_line.pb.h"
#include "xict_proto/sensor/can.pb.h"
#include "xict_ui_common/utils/utils.h"
#include "xict_ui_driver/utils/basecansdk.h"
#include <QDateTime>
#include <QObject>
#include <QProcess>
#include <QThread>
#include <QTimer>
#include <QUdpSocket>
#include <ecal/msg/protobuf/publisher.h>

namespace xict_ui_core {

    class CanManager : public QObject {
        Q_OBJECT
        BJ_PROPERTY(int, camera_changed);

        //------------铲运机车辆运行关键参数--------------//
        BJ_PROPERTY(int, engine_speed);
        BJ_PROPERTY(int, coolant_temperature);
        BJ_PROPERTY(int, oil_pressure);
        BJ_PROPERTY(int, oil_temperature);
        BJ_PROPERTY(float, engine_operating_time);
        BJ_PROPERTY(float, engine_total_fuel_consumption);
        BJ_PROPERTY(float, arm_angle);
        BJ_PROPERTY(int, fuel_level);
        BJ_PROPERTY(float, turn_angle);
        BJ_PROPERTY(float, bucket_angle);
        BJ_PROPERTY(float, arm_height);
        BJ_PROPERTY(float, vehicle_angle_x);
        BJ_PROPERTY(float, vehicle_angle_y);
        BJ_PROPERTY(float, speed);
        BJ_PROPERTY(int, forward_back_signal);
        BJ_PROPERTY(bool, parking_signal);
        BJ_PROPERTY(int, gear);
        BJ_PROPERTY(bool, control_change);
        BJ_PROPERTY(bool, low_power_ready_status);
        BJ_PROPERTY(bool, low_power_status);
        BJ_PROPERTY(int, control_mode);
        BJ_PROPERTY(int, mode_status);
        BJ_PROPERTY(int, penzhuang_status);
        BJ_PROPERTY(int, stop_);
        //------------铲运机车辆运行关键参数--------------//

        //------------铲运机异常状态或报警----------------//
        BJ_PROPERTY(
            bool,
            error_communication_vehicle_controller_and_console_controller);
        BJ_PROPERTY(bool, error_anticollision_limited_action);
        BJ_PROPERTY(bool, error_communication_imu);
        BJ_PROPERTY(bool, error_communication_biaxial_inclination_sensor);
        BJ_PROPERTY(bool,
                    error_communication_vehicle_pc_and_vehicle_controller);
        BJ_PROPERTY(bool, error_communication_left_handle);
        BJ_PROPERTY(bool, error_communication_right_handle);
        BJ_PROPERTY(bool, error_communication_left_button_borad);
        BJ_PROPERTY(bool, error_communication_right_front_button_board);
        BJ_PROPERTY(bool, error_communication_engine);
        BJ_PROPERTY(bool, error_communication_right_back_button_board);
        BJ_PROPERTY(bool,
                    error_communication_vehicle_controller_and_console_pc);
        BJ_PROPERTY(bool, error_engine_air_filter_clogged);
        BJ_PROPERTY(bool, error_low_hydraulic_oil_level);
        BJ_PROPERTY(bool, error_low_transmission_oil_level);
        BJ_PROPERTY(bool, error_low_fuel_level);
        BJ_PROPERTY(bool, error_high_hydraulic_oil_temperature);
        BJ_PROPERTY(bool, error_connection_left_front_ultrasonic_radar);
        BJ_PROPERTY(bool, error_connection_left_back_ultrasonic_radar);
        BJ_PROPERTY(bool, error_connection_right_front_ultrasonic_radar);
        BJ_PROPERTY(bool, error_connection_right_back_ultrasonic_radar);
        BJ_PROPERTY(bool, error_connection_corner_angle_displacement_sensor);
        BJ_PROPERTY(bool, error_connection_arm_angle_displacement_sensor);
        BJ_PROPERTY(bool, error_connection_bucket_angle_displacement_sensor);
        BJ_PROPERTY(bool, error_speed_sensor);
        BJ_PROPERTY(bool, error_communication_front_lidar);
        BJ_PROPERTY(bool, error_communication_back_lidar);
        BJ_PROPERTY(bool, error_solenoid_valve_disconnected_turn_left);
        BJ_PROPERTY(bool, error_solenoid_valve_disconnected_turn_right);
        BJ_PROPERTY(bool, error_solenoid_valve_disconnected_arm_up);
        BJ_PROPERTY(bool, error_solenoid_valve_disconnected_arm_down);
        BJ_PROPERTY(bool, error_solenoid_valve_disconnected_bucket_up);
        BJ_PROPERTY(bool, error_solenoid_valve_disconnected_bucket_down);
        BJ_PROPERTY(bool, error_network_latency);
        BJ_PROPERTY(bool, error_low_voltage);
        BJ_PROPERTY(bool, error_vehicle_lean);
        BJ_PROPERTY(bool, error_solenoid_valve_forward);
        BJ_PROPERTY(bool, error_solenoid_valve_back);
        BJ_PROPERTY(bool, error_front_lidar_mirror_contamination);
        BJ_PROPERTY(bool, error_back_lidar_mirror_contamination);
        BJ_PROPERTY(bool, error_communication_safety_door_a);
        BJ_PROPERTY(bool, error_communication_safety_door_b);
        BJ_PROPERTY(bool, error_invasions_safety_door_a);
        BJ_PROPERTY(bool, error_invasions_safety_door_b);
        //------------铲运机异常状态或报警----------------//

        BJ_PROPERTY(bool, key_screen_switch_enabled);      // 屏幕切换
        BJ_PROPERTY(bool, key_data_load_query_enabled);    // 装载数据查询
        BJ_PROPERTY(bool, key_decrement_bucket_enabled);   // 减一斗
        BJ_PROPERTY(bool,
                    key_lattice_limit_release_enabled);   // 光栅门限动解除
        BJ_PROPERTY(bool,
                    key_sensor_limit_release_enabled);   // 车身传感器限动解除
        BJ_PROPERTY(bool, key_door_lock_override_enabled);   // 门锁越权
        BJ_PROPERTY(bool, key_f1_enabled);                   // F1
        BJ_PROPERTY(bool, key_ok_enabled);                   // F2

    public:
        CanManager(QObject* parent = nullptr);
        ~CanManager();
        struct can_msgs {
            uint8_t dlc;
            int id;
            uint8_t data[8];
            bool is_rtr;
            bool is_extended;
        };
        void init();
        Q_INVOKABLE void start();
        Q_INVOKABLE void enableVehicleType(int vehicle_type);
        Q_INVOKABLE void disenableVehicleType();

        void canToVehicleUdp(const can_msgs can_rx_msg_ptr);
        void canToCockpitUdp(const can_msgs can_rx_msg_ptr);
        Q_INVOKABLE void sendUdpState(int index);
        Q_INVOKABLE void sendKeyData(const QVector<int>& pressStates);
        Q_INVOKABLE void sendLineData(const QVector<int>& line_state);
        Q_INVOKABLE void sendSetZeroHeight(bool set_zero);
        Q_INVOKABLE void shutdownSystem();
        Q_INVOKABLE void runShellScript();
        Q_INVOKABLE void stopShellScript();

    public slots:
        void update_grader_can(const xcmg_proto::Grader_CAN& msgs);
        void update_loader_can(const xcmg_proto::Loader_CAN& msgs);
        // void update_imu_can(const xcmg_proto::IMU& msgs);
        void update_scraper_can(const xcmg_proto::Scraper_CAN& can_msg);

    private:
        QUdpSocket* m_udpSender;
        QUdpSocket* m_cockpit_udpSender;
        eCAL::protobuf::CPublisher<xcmg_proto::lane_line>* m_linePub;

        QString m_ip;
        qint64 m_port;
        QString m_cockpit_ip;
        qint64 m_cockpit_port;
        QTimer* m_timer;
        QProcess* process_wika;
        QThread* m_can_thread;
        xict_ui_driver::CanSdk* m_can_sdk;
    };

}   // namespace xict_ui_core

#endif   // CANMANAGE_H
